home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 41 / Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso / -seriously_amiga- / misc / xpdf_0.8 / xpdf_src / goo / parseargs.c < prev    next >
C/C++ Source or Header  |  1999-04-28  |  3KB  |  191 lines

  1. /*
  2.  * parseargs.h
  3.  *
  4.  * Command line argument parser.
  5.  *
  6.  * Copyright 1996 Derek B. Noonburg
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <stddef.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <ctype.h>
  14. #include "parseargs.h"
  15.  
  16. static ArgDesc *findArg(ArgDesc *args, char *arg);
  17. static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]);
  18.  
  19. GBool parseArgs(ArgDesc *args, int *argc, char *argv[]) {
  20.   ArgDesc *arg;
  21.   int i, j;
  22.   GBool ok;
  23.  
  24.   ok = gTrue;
  25.   i = 1;
  26.   while (i < *argc) {
  27.     if (!strcmp(argv[i], "--")) {
  28.       --*argc;
  29.       for (j = i; j < *argc; ++j)
  30.     argv[j] = argv[j+1];
  31.       break;
  32.     } else if ((arg = findArg(args, argv[i]))) {
  33.       if (!grabArg(arg, i, argc, argv))
  34.     ok = gFalse;
  35.     } else {
  36.       ++i;
  37.     }
  38.   }
  39.   return ok;
  40. }
  41.  
  42. void printUsage(char *program, char *otherArgs, ArgDesc *args) {
  43.   ArgDesc *arg;
  44.   char *typ;
  45.   int w, w1;
  46.  
  47.   w = 0;
  48.   for (arg = args; arg->arg; ++arg) {
  49.     if ((w1 = strlen(arg->arg)) > w)
  50.       w = w1;
  51.   }
  52.  
  53.   fprintf(stderr, "Usage: %s [options]", program);
  54.   if (otherArgs)
  55.     fprintf(stderr, " %s", otherArgs);
  56.   fprintf(stderr, "\n");
  57.  
  58.   for (arg = args; arg->arg; ++arg) {
  59.     fprintf(stderr, "  %s", arg->arg);
  60.     w1 = 9 + w - strlen(arg->arg);
  61.     switch (arg->kind) {
  62.     case argInt:
  63.     case argIntDummy:
  64.       typ = " <int>";
  65.       break;
  66.     case argFP:
  67.     case argFPDummy:
  68.       typ = " <fp>";
  69.       break;
  70.     case argString:
  71.     case argStringDummy:
  72.       typ = " <string>";
  73.       break;
  74.     case argFlag:
  75.     case argFlagDummy:
  76.     default:
  77.       typ = "";
  78.       break;
  79.     }
  80.     fprintf(stderr, "%-*s", w1, typ);
  81.     if (arg->usage)
  82.       fprintf(stderr, ": %s", arg->usage);
  83.     fprintf(stderr, "\n");
  84.   }
  85. }
  86.  
  87. static ArgDesc *findArg(ArgDesc *args, char *arg) {
  88.   ArgDesc *p;
  89.  
  90.   for (p = args; p->arg; ++p) {
  91.     if (p->kind < argFlagDummy && !strcmp(p->arg, arg))
  92.       return p;
  93.   }
  94.   return NULL;
  95. }
  96.  
  97. static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]) {
  98.   int n;
  99.   int j;
  100.   GBool ok;
  101.  
  102.   ok = gTrue;
  103.   n = 0;
  104.   switch (arg->kind) {
  105.   case argFlag:
  106.     *(GBool *)arg->val = gTrue;
  107.     n = 1;
  108.     break;
  109.   case argInt:
  110.     if (i + 1 < *argc && isInt(argv[i+1])) {
  111.       *(int *)arg->val = atoi(argv[i+1]);
  112.       n = 2;
  113.     } else {
  114.       ok = gFalse;
  115.       n = 1;
  116.     }
  117.     break;
  118.   case argFP:
  119.     if (i + 1 < *argc && isFP(argv[i+1])) {
  120.       *(double *)arg->val = atof(argv[i+1]);
  121.       n = 2;
  122.     } else {
  123.       ok = gFalse;
  124.       n = 1;
  125.     }
  126.     break;
  127.   case argString:
  128.     if (i + 1 < *argc) {
  129.       strncpy((char *)arg->val, argv[i+1], arg->size - 1);
  130.       ((char *)arg->val)[arg->size - 1] = '\0';
  131.       n = 2;
  132.     } else {
  133.       ok = gFalse;
  134.       n = 1;
  135.     }
  136.     break;
  137.   default:
  138.     fprintf(stderr, "Internal error in arg table\n");
  139.     n = 1;
  140.     break;
  141.   }
  142.   if (n > 0) {
  143.     *argc -= n;
  144.     for (j = i; j < *argc; ++j)
  145.       argv[j] = argv[j+n];
  146.   }
  147.   return ok;
  148. }
  149.  
  150. GBool isInt(char *s) {
  151.   if (*s == '-' || *s == '+')
  152.     ++s;
  153.   while (isdigit(*s))
  154.     ++s;
  155.   if (*s)
  156.     return gFalse;
  157.   return gTrue;
  158. }
  159.  
  160. GBool isFP(char *s) {
  161.   int n;
  162.  
  163.   if (*s == '-' || *s == '+')
  164.     ++s;
  165.   n = 0;
  166.   while (isdigit(*s)) {
  167.     ++s;
  168.     ++n;
  169.   }
  170.   if (*s == '.')
  171.     ++s;
  172.   while (isdigit(*s)) {
  173.     ++s;
  174.     ++n;
  175.   }
  176.   if (n > 0 && (*s == 'e' || *s == 'E')) {
  177.     ++s;
  178.     if (*s == '-' || *s == '+')
  179.       ++s;
  180.     n = 0;
  181.     if (!isdigit(*s))
  182.       return gFalse;
  183.     do {
  184.       ++s;
  185.     } while (isdigit(*s));
  186.   }
  187.   if (*s)
  188.     return gFalse;
  189.   return gTrue;
  190. }
  191.